package com.api.user.service.impl;

import com.api.base.model.SysUserRole;
import com.api.base.service.SysUserRoleService;
import com.api.user.dao.CouponMapper;
import com.api.user.model.*;
import com.api.user.service.CouponService;
import com.api.core.service.AbstractService;
import com.api.user.service.CouponUserService;
import com.api.user.utils.DateUtil;
import com.api.user.utils.MathUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

import com.api.common.JSONUtils;
import com.api.core.response.Result;
import com.api.core.response.ResultGenerator;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * Created by wanghuiwen on 2021/04/12.
 */
@Service
@Transactional
public class CouponServiceImpl extends AbstractService<Coupon> implements CouponService {
    @Resource
    private CouponMapper couponMapper;

    @Resource
    private SysUserRoleService sysUserRoleService;

    @Resource
    private CouponUserService couponUserService;
    @Override
    public Result list( Map<String, Object> params, String order, Integer page, Integer size){
//        Map<String, Object> params = JSONUtils.json2map(search);
        Map<String, Object> orderParams = JSONUtils.json2map(order);
        for (String key : orderParams.keySet()) {
                if (orderParams.get(key) != null && orderParams.get(key).equals("ascending")) orderParams.put(key, "asc");
                if (orderParams.get(key) != null && orderParams.get(key).equals("descending")) orderParams.put(key, "desc");
            }
        PageHelper.startPage(page, size);
        List<Map<String, Object>> res = couponMapper.list(params, orderParams);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(res);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @Override
    public Result add(CouponAdd add) {
        if(null == add.getCouponId()){
            Coupon coupon = new Coupon();
            coupon.setCouponCategory(add.getCouponCategory());
            coupon.setCouponMin(add.getCouponMin());
            coupon.setCouponMode(add.getCouponMode());
            coupon.setCouponTitle(add.getCouponTitle());
            coupon.setDenomination(add.getDenomination());
            coupon.setEndTime(add.getEndTime());
            coupon.setQuantity(add.getQuantity());
            coupon.setRemark(add.getRemark());
            coupon.setStartTime(add.getStartTime());
            coupon.setState(add.getState());
            coupon.setTimeMode(add.getTimeMode());
            coupon.setUserLimit(add.getUserLimit());
            coupon.setValidityDay(add.getValidityDay());
            coupon.setCreateTime(new Date().getTime());

            this.save(coupon);
        }else{
            Coupon coupon = this.findById(add.getCouponId());
            coupon.setCouponCategory(add.getCouponCategory());
            coupon.setCouponMin(add.getCouponMin());
            coupon.setCouponMode(add.getCouponMode());
            coupon.setCouponTitle(add.getCouponTitle());
            coupon.setDenomination(add.getDenomination());
            coupon.setEndTime(add.getEndTime());
            coupon.setQuantity(add.getQuantity());
            coupon.setRemark(add.getRemark());
            coupon.setStartTime(add.getStartTime());
            coupon.setState(add.getState());
            coupon.setTimeMode(add.getTimeMode());
            coupon.setUserLimit(add.getUserLimit());
            coupon.setValidityDay(add.getValidityDay());
            this.update(coupon);
        }
        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Result receive(Long couponId, Long userId) {

        Coupon coupon = this.findById(couponId);
        //判断优惠券状态
        if(coupon.getState() == 2){
            return ResultGenerator.genFailResult(400,"Coupon cancelled");
        }
        //判断优惠券有效期
        if(coupon.getTimeMode()==1){
            Long current = new Date().getTime();
            if(coupon.getEndTime()<=current){
                return ResultGenerator.genFailResult(400,"Coupon has expired");
            }
        }
        //判断是否超过发放数量
        List<CouponUser> couponUsers = couponUserService.getByCouponId(couponId);
        if(couponUsers.size()>=coupon.getQuantity()){
            return ResultGenerator.genFailResult(400,"Coupon is fully redeemed");
        }
        //判断是否超过用户可领取数量
        List<CouponUser> couponUsers1 = couponUserService.getByUserIdAndCouponId(userId,couponId);
//        if(couponUsers1.size()>=coupon.getUserLimit()){
//            return ResultGenerator.genFailResult(400,"一个用户最多只能领取"+coupon.getUserLimit()+"个优惠券");
//        }

        CouponUser couponUser = new CouponUser();
        couponUser.setCouponId(couponId);
        couponUser.setUserId(userId);
        couponUser.setReceiveTime(new Date().getTime());
        couponUser.setCouponAmount(coupon.getDenomination());
        if(coupon.getTimeMode()==1){
            couponUser.setValidityTime(coupon.getEndTime());
        }else{
            Date date = DateUtil.rollDay(new Date(),coupon.getValidityDay());
            Long time = DateUtil.getTime(date);
            couponUser.setValidityTime(time);
        }
        String couponCode = this.getCouponCode();
        couponUser.setCouponCode(couponCode);
        couponUser.setStatus(false);
        couponUserService.save(couponUser);
        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Result apply(CouponUse couponUse) {

        CouponUser couponUser = couponUserService.findBy("couponCode",couponUse.getCouponCode());
        if(couponUser.getStatus()){
            return ResultGenerator.genFailResult(400,"优惠券已经使用");
        }
        if(couponUser.getValidityTime()<=new Date().getTime()){
            return ResultGenerator.genFailResult(400,"优惠券已经过期");
        }
        Coupon coupon = this.findById(couponUser.getCouponId());
        if(coupon.getCouponCategory().equals(3)){
            return ResultGenerator.genFailResult(400,"优惠券只能用于陪玩");
        }
        if(coupon.getCouponMode()==1 && couponUse.getTotalAmount().compareTo(new BigDecimal(coupon.getCouponMin())) < 0){
            return ResultGenerator.genFailResult(400,"低于优惠券使用门槛");
        }
        Map<String,Object> map = new HashMap<>();
        map.put("couponId",couponUser.getCouponId());
        map.put("couponAmount",coupon.getDenomination());
        return ResultGenerator.genSuccessResult(map);
    }

    @Override
    public Result listUser(Long userId) {
        SysUserRole userRole =sysUserRoleService.getByUserId(userId);

        List<Map<String,Object>> res = couponMapper.listUser(userRole.getRoleId());
        Iterator<Map<String,Object>> iterator =res.iterator();
        while (iterator.hasNext()){
            Map<String,Object> map = iterator.next();
            Integer quantity =(Integer) map.get("quantity");
            Long couponId =(Long) map.get("couponId");
            List<CouponUser> couponUsers = couponUserService.getByCouponId(couponId);
            if(couponUsers.size()>=quantity){
                iterator.remove();
                continue;
            }
            Integer userLimit =(Integer) map.get("userLimit");

            List<CouponUser> couponUsers1 = couponUserService.getByUserIdAndCouponId(userId,couponId);
            if(couponUsers1.size()>=userLimit){
                iterator.remove();
            }
        }
        return ResultGenerator.genSuccessResult(res);
    }

    @Override
    public Result my(Long userId, String code, Map<String, Object> orderParams) {

        List<Map<String,Object>> res = couponUserService.getCouponByUserId(userId,code,orderParams);
        return ResultGenerator.genSuccessResult(res);
    }

    public String getCouponCode(){
        String a = MathUtil.getStringRandom(10);
        CouponUser couponUser = couponUserService.findBy("couponCode",a);
        if(null != couponUser){
            a = getCouponCode();
        }
        return a;

    }

    @Override
    public Result delete(Long id) {
        Coupon coupon = findById(id);
        coupon.setState(2);
        update(coupon);
        return ResultGenerator.genSuccessResult();
    }
}
